-- Mostly taken from Trouble in Terrorist Town, credits to Bad King Urgrain.

MSTACK = {}

MSTACK.msgs = {}
MSTACK.last = 0

surface.CreateFont("Default", 20, 100, true, true, "Notification")
local font = "Notification"

local margin = 6
local msg_width = 400

local text_width = msg_width - (margin * 3)

local text_height = draw.GetFontHeight(font)

local top_y = -margin
-- local top_x = ScrW() - margin - msg_width
local top_x = ScrW()/2

local appear_time = 12
local max_items = 8

local fadein = 0.1
local fadeout = 0.6

local movespeed = 2

local colors = {
	generic_text = Color(255, 255, 255, 210),
	zombie_text = Color(176, 60, 60, 210),

	background = Color(0, 0, 0, 200)
};

MSTACK.width = msg_width + margin

function MSTACK:AddColoredMessage(text, clr)
	local item = {}
	item.text = self:WrapText(text, text_width)

	item.height = (#item.text * text_height) + (margin * (1 + #item.text))

	item.col = clr or colors.generic_text
	item.time = CurTime()
	item.sounded = false
	item.move_y = -item.height

	if self.last > (item.time - 1) then
		item.time = self.last + 1
	end

	table.insert(self.msgs, 1, item)

	self.last = item.time
end

function MSTACK:AddMessage(text, zombie)
	self:AddColoredMessage(text, zombie and colors.zombie_text or colors.generic_text)
end
function MSTACK:WrapText(text, width)
	surface.SetFont(font)

	local w, _ = surface.GetTextSize(text)
	if w <= width then
		return {text}
	end
   
	local words = string.Explode(" ", text)

	local lines = {""}
	for i, wrd in pairs(words) do
		local l = #lines
		local added = lines[l] .. " " .. wrd
		w, _ = surface.GetTextSize(added)

		if w > text_width then
			table.insert(lines, wrd)
		else
			lines[l] = added
		end
	end

	return lines
end

local msg_sound = Sound("Hud.Hint")

local bg_orig = colors.background
function MSTACK:Draw(client)
	if next(self.msgs) == nil then return end

	local running_y = top_y
	for k, item in pairs(self.msgs) do
		if item.time < CurTime() then
			if item.sounded == false then
				client:EmitSound(msg_sound, 80, 250)
				item.sounded = true
			end

			local y = running_y + margin + item.move_y

			item.move_y = (item.move_y < 0) and item.move_y + movespeed or 0

			local delta = (item.time + appear_time) - CurTime()
			delta = delta/appear_time

			if k >= max_items then
				delta = delta/2
			end

			local alpha = 255

			if delta > 1 - fadein then
				alpha = math.Clamp((1.0 - delta) * (255/fadein), 0, 255)
			elseif delta < fadeout then
				alpha = math.Clamp(delta * (255/fadeout), 0, 255)
			end

			local height = item.height

			local bg_col = Color(bg_orig.r, bg_orig.g, bg_orig.b, math.Clamp(alpha, 0, bg_orig.a))
			draw.RoundedBox(4, top_x - (msg_width/2), y, msg_width, height, bg_col)

			local txt_col = table.Copy(item.col)
			txt_col.a = math.Clamp(alpha, 0, txt_col.a)

			local spec = {}
			spec.font=font
			spec.xalign = TEXT_ALIGN_CENTER
			spec.yalign = TEXT_ALIGN_TOP
			spec.color = txt_col

			for i = 1, #item.text do
				spec.text=item.text[i]

				local tx = top_x--  + (msg_width/2)
				local ty = y + margin + (i - 1) * (text_height + margin)
				spec.pos={tx, ty}

				draw.Text(spec)
			end

			if alpha == 0 then 
				self.msgs[k] = nil 
			end

			running_y = y + height
		end
	end
end

local function ReceiveGameMsg(um)
	local text = um:ReadString()
	local special = um:ReadBool()

	print(text)

	MSTACK:AddMessage(text, special)
end
usermessage.Hook("game_msg", ReceiveGameMsg)

local function ReceiveCustomMsg(um)
	local text = um:ReadString()
	local clr = Color(255, 255, 255)

	clr.r = um:ReadShort()
	clr.g = um:ReadShort()
	clr.b = um:ReadShort()

	print(text)

	MSTACK:AddColoredMessage(text, clr)
end
usermessage.Hook("game_msg_color", ReceiveCustomMsg)

